/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.dreamsoft.Expression;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author rafael
 */
public class ExpressionCalc {

    private final String[] OPS = {"*", "/", "+-"};
    private int indice = 0;
    private Pattern pattern;
    private Matcher matcher;
    private String exp;

    public ExpressionCalc(String exp) {
        this.exp = exp;
    }

    public String calcular() throws ArithmeticException, NumberFormatException, Exception {
        
            //função regex que procura por numero inteiro ou double ([\\d\\.]+) seguidos de um operador
            //e seguidos de um numero inteiro ou double
            this.pattern = Pattern.compile("[\\d\\.]+[\\" + OPS[indice] + "][\\d\\.]+");
            //this.p = Pattern.compile("\\d\\*\\d");
            matcher = this.pattern.matcher(this.exp);

            StringBuffer sb = new StringBuffer();
            double resultParcial = 0;
            //mult
            if (matcher.find()) {
                //pega somente o operador
                char op = matcher.group().split("[\\d\\.]+")[1].charAt(0);
                //pega os numeros
                String valores[] = matcher.group().split("[\\" + OPS[indice] + "]");
                switch (op) {
                    case '*':
                        resultParcial = Double.parseDouble(valores[0]) * Double.parseDouble(valores[1]);
                        break;
                    case '+':
                        resultParcial = Double.parseDouble(valores[0]) + Double.parseDouble(valores[1]);
                        break;
                    case '-':
                        resultParcial = Double.parseDouble(valores[0]) - Double.parseDouble(valores[1]);
                        break;
                    case '/':
                        resultParcial = Double.parseDouble(valores[0]) / Double.parseDouble(valores[1]);
                        break;
                    default:
                        throw new Exception("Houve um erro com os operadores!");
                }

                //atribui a sb a string inicial mais o valor de resultParcial
                matcher.appendReplacement(sb, String.valueOf(resultParcial));
                matcher.appendTail(sb);
                this.exp = sb.toString();
                //continua ate resolver todas as operações para um determinado operador
                calcular();
            } else {//incrementa o indice e calcula os resultados com o proximo operador
                indice++;
                if (indice < OPS.length) {
                    calcular();
                }
            }
        
            //zera o indice novamente
            indice = 0;
            return this.exp;        
    }
}
